<html>
	<head>
		<script src="../../src/gears_init.js"></script>
		<script src="../../src/Norm.js"></script>
		<script src="../../src/Norm.Logger.Gears.js"></script>
		<script src="../../src/Norm.Database.Gears.js"></script>
		<script src="../../src/Norm.ResultIterator.Gears.js"></script>
		<script src="../../src/Norm.LastIdManager.js"></script>
		<script src="../../src/Norm.Events.js"></script>
		<script src="../../src/Norm.Sql.js"></script>
		<script src="../../src/Norm.Fields.js"></script>
		<script src="../../src/Norm.Model.js"></script>
		<script src="../../src/Norm.Introspection.js"></script>
		<script src="../../src/Norm.Transaction.js"></script>
		<script>
			Norm.Database.name = "test.relations";
			var Company = new Norm.Model({
				name : "Company",
				fields : {
					name : new Norm.Fields.String({maxLength : 25}),
					people : new Norm.Fields.ManyToOne({related : "Person"})
				}
			});
			
			var Person = new Norm.Model({
				name : "Person",
				fields : {
					firstName : new Norm.Fields.String({maxLength : 25}),
					lastName : new Norm.Fields.String({maxLength : 25}),
					company : new Norm.Fields.OneToMany({related : "Company", onDeleteCascade : true})
				}
			});
			
			var Tests = {
				
				up : function() {
					
					Company.dropTable();
					Person.dropTable();
					Company.createTable();
					Person.createTable();
					(new Company({name : "Company1"})).save();
					(new Company({name : "Company2"})).save();
				},
				
				"test if create works with relation" : function() {
					
					var someone = new Person();
					someone.firstName = "John";
					someone.lastName = "Doe";
					someone.company = Company.select("name = ?", ["Company1"]).getOne();
					Norm.log("someone.company: " + someone.company);
					someone.save();
					Norm.log("someone.rowid: " + someone.rowid);
					UnitTest.assertDefined(someone.rowid);
					var someone2 = new Person();
					someone2.firstName = "John";
					someone2.lastName = "Doe";
					someone2.company = Company.select("name = ?", ["Company2"]).getOne();
					Norm.log("someone2.company: " + someone2.company);
					someone2.save();
					Norm.log("someone2.rowid: " + someone2.rowid);
					UnitTest.assertDefined(someone2.rowid);
				},
				
				"test select from backward relation" : function() {
					
					var company1 = Company.select("name = ?", ["Company1"]).getOne();
					//var company2 = Company.select("name = ?", ["Company2"]).getOne();
					//Norm.log("company1.rowid: " + company1.rowid);
					//Norm.log("company2.rowid: " + company2.rowid);
					//Norm.log("company1.people.select().toArray().length: " + company1.people.select().toArray().length);
					//Norm.log("company2.people.select().toArray().length: " + company2.people.select().toArray().length);
					
					UnitTest.assertTrue(
						company1.people.select().toArray().length == 1,
						"there should be only one person in company1"
					);	
				},
				
				"test remove from backward relation" : function() {
					
					var company2 = Company.select("name = ?", ["Company2"]).getOne();
					var someone2 = new Person(2);
					someone2.remove();
					UnitTest.assertTrue(
						company2.people.select().getOne() == false,
						"someone from company2 wasn`t deleted"
					);
				},
				
				"test cascade on delete" : function() {
					
					var aCompany = new Company();
					aCompany.name = "aCompany";
					aCompany.save();
					var aPerson = new Person();
					aPerson.firstName = "John";
					aPerson.lastName = "Doe";
					aPerson.company = aCompany;
					aPerson.save();
					aCompany.remove();
					UnitTest.assertTrue(
						aCompany.people.select().getOne() == false,
						"person wasn`t deleted"
					);
					aCompany.remove();
				},
				
				"test if foreign key is enforced in a insert" : function() {
					
					var someone = new Person();
					someone.firstName = "John";
					someone.lastName = "Doe";
					someone.company = 100;					// an invalid company value
					try {
						someone.save();
					} catch(e) {
						return;
					}
					throw new Error("an exception didn`t happen even though the insert violates the foreign key");
				},
				
				"test if foreign key is enforced in a update" : function() {
					
					var someone = new Person();
					someone.firstName = "John";
					someone.lastName = "Doe";
					someone.company = 1;
					someone.save();
					try {
						someone.company = 100;				// an invalid company value
						someone.save();
					} catch(e) {
						return;
					}
					throw new Error("a exception didn`t happen even though the insert violates the foreign key");
				},
				
				down : function() {
					
					Person.dropTable();
					Company.dropTable();
				}
			};
		</script>
		<script src="unit-test.js"></script>
	</head>
	<body>
		
	</body>
</html>
